/*!
 * \file test_data_interfaces_comprehensive.cpp
 * \brief 数据读写接口综合测试
 */

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <memory>
#include <thread>
#include <chrono>
#include <atomic>
#include <vector>
#include <string>

#include "../../src/Includes/IDataReader.h"
#include "../../src/Includes/IDataWriter.h"
#include "../../src/Includes/WTSTypes.h"
#include "../../src/Includes/WTSObject.hpp"
#include "../../src/Includes/WTSCollection.hpp"
#include "../../src/Includes/WTSVariant.hpp"

USING_NS_WTP;

/*!
 * \brief Mock基础数据管理器
 */
class MockIBaseDataMgr : public IBaseDataMgr {
public:
    MOCK_METHOD(WTSCommodityInfo*, getCommodity, (const char* exchg, const char* pid), (override));
    MOCK_METHOD(WTSCommodityInfo*, getCommodity, (const char* stdCode), (override));
    MOCK_METHOD(WTSSessionInfo*, getSession, (const char* sid), (override));
    MOCK_METHOD(WTSSessionInfo*, getSessionByCode, (const char* stdCode), (override));
    MOCK_METHOD(WTSContractInfo*, getContract, (const char* stdCode), (override));
    MOCK_METHOD(WTSContractInfo*, getContract, (const char* exchg, const char* code), (override));
    MOCK_METHOD(WTSArray*, getContracts, (const char* exchg), (override));
    MOCK_METHOD(WTSArray*, getAllContracts, (), (override));
    MOCK_METHOD(bool, isHoliday, (const char* pid, uint32_t uDate, bool isTpl), (override));
    MOCK_METHOD(uint32_t, calcTradingDate, (const char* pid, uint32_t uDate, uint32_t uTime, bool isSession), (override));
    MOCK_METHOD(uint64_t, getBoundaryTime, (const char* stdCode, uint32_t tDate, bool isStart, bool isSession), (override));
    MOCK_METHOD(void, release, (), (override));
};

/*!
 * \brief Mock热门合约管理器
 */
class MockIHotMgr : public IHotMgr {
public:
    MOCK_METHOD(bool, isHot, (const char* stdCode), (override));
    MOCK_METHOD(const char*, getRawCode, (const char* stdCode), (override));
    MOCK_METHOD(const char*, getPrevRawCode, (const char* stdCode, uint32_t dt), (override));
    MOCK_METHOD(bool, splitHotSecions, (const char* stdCode, uint32_t sDt, uint32_t eDt, HotSections& sections), (override));
    MOCK_METHOD(void, release, (), (override));
};

/*!
 * \brief Mock数据读取回调接口
 */
class MockIDataReaderSink : public IDataReaderSink {
public:
    MOCK_METHOD(void, on_bar, (const char* stdCode, WTSKlinePeriod period, WTSBarStruct* newBar), (override));
    MOCK_METHOD(void, on_all_bar_updated, (uint32_t updateTime), (override));
    MOCK_METHOD(IBaseDataMgr*, get_basedata_mgr, (), (override));
    MOCK_METHOD(IHotMgr*, get_hot_mgr, (), (override));
    MOCK_METHOD(uint32_t, get_date, (), (override));
    MOCK_METHOD(uint32_t, get_min_time, (), (override));
};

/*!
 * \brief Mock历史数据加载器
 */
class MockIHisDataLoader : public IHisDataLoader {
public:
    MOCK_METHOD(bool, loadFinalHisBars, (void* obj, const char* stdCode, WTSKlinePeriod period, FuncReadBars cb), (override));
    MOCK_METHOD(bool, loadRawHisBars, (void* obj, const char* stdCode, WTSKlinePeriod period, FuncReadBars cb), (override));
    MOCK_METHOD(bool, loadAllAdjFactors, (void* obj, FuncReadFactors cb), (override));
    MOCK_METHOD(bool, loadAdjFactors, (void* obj, const char* stdCode, FuncReadFactors cb), (override));
};

/*!
 * \brief Mock数据读取器
 */
class MockIDataReader : public IDataReader {
private:
    std::map<std::string, std::vector<WTSBarStruct>> kline_data_;
    std::map<std::string, std::vector<WTSTickStruct>> tick_data_;

public:
    MOCK_METHOD(void, onMinuteEnd, (uint32_t uDate, uint32_t uTime, uint32_t endTDate), (override));
    
    virtual WTSTickSlice* readTickSlice(const char* stdCode, uint32_t count, uint64_t etime = 0) override {
        // 简单实现用于测试
        return nullptr;
    }
    
    virtual WTSKlineSlice* readKlineSlice(const char* stdCode, WTSKlinePeriod period, uint32_t count, uint64_t etime = 0) override {
        // 简单实现用于测试
        return nullptr;
    }
    
    virtual double getAdjFactorByDate(const char* stdCode, uint32_t date = 0) override {
        return 1.0;
    }
    
    // 测试辅助方法
    void addTestKlineData(const std::string& code, const WTSBarStruct& bar) {
        kline_data_[code].push_back(bar);
    }
    
    size_t getKlineDataCount(const std::string& code) const {
        auto it = kline_data_.find(code);
        return it != kline_data_.end() ? it->second.size() : 0;
    }
};

/*!
 * \brief Mock数据写入回调接口
 */
class MockIDataWriterSink : public IDataWriterSink {
public:
    MOCK_METHOD(IBaseDataMgr*, get_basedata_mgr, (), (override));
    MOCK_METHOD(bool, canSessionReceive, (const char* sid), (override));
    MOCK_METHOD(void, broadcastTick, (WTSTickData* curTick), (override));
    MOCK_METHOD(void, broadcastOrdQue, (WTSOrdQueData* curOrdQue), (override));
    MOCK_METHOD(void, broadcastOrdDtl, (WTSOrdDtlData* curOrdDtl), (override));
    MOCK_METHOD(void, broadcastTrans, (WTSTransData* curTrans), (override));
    MOCK_METHOD(CodeSet*, getSessionComms, (const char* sid), (override));
    MOCK_METHOD(uint32_t, getTradingDate, (const char* pid), (override));
    MOCK_METHOD(void, outputLog, (WTSLogLevel ll, const char* message), (override));
};

/*!
 * \brief Mock历史数据导出器
 */
class MockIHisDataDumper : public IHisDataDumper {
public:
    MOCK_METHOD(bool, dumpHisBars, (const char* stdCode, const char* period, WTSArray* ayBars, FuncCreateWriter creator), (override));
    MOCK_METHOD(bool, dumpHisTicks, (const char* stdCode, uint32_t uDate, WTSArray* ayTicks, FuncCreateWriter creator), (override));
    MOCK_METHOD(bool, dumpHisOrdQue, (const char* stdCode, uint32_t uDate, WTSArray* ayOrdQue, FuncCreateWriter creator), (override));
    MOCK_METHOD(bool, dumpHisOrdDtl, (const char* stdCode, uint32_t uDate, WTSArray* ayOrdDtl, FuncCreateWriter creator), (override));
    MOCK_METHOD(bool, dumpHisTrans, (const char* stdCode, uint32_t uDate, WTSArray* ayTrans, FuncCreateWriter creator), (override));
};

/*!
 * \brief Mock数据写入器
 */
class MockIDataWriter : public IDataWriter {
private:
    std::atomic<int> tick_count_;
    std::atomic<int> ordque_count_;
    std::atomic<int> orddtl_count_;
    std::atomic<int> trans_count_;

public:
    MockIDataWriter() : tick_count_(0), ordque_count_(0), orddtl_count_(0), trans_count_(0) {}
    
    MOCK_METHOD(void, release, (), (override));
    
    virtual bool writeTick(WTSTickData* curTick, uint32_t procFlag) override {
        if (curTick) {
            tick_count_++;
            return true;
        }
        return false;
    }
    
    virtual bool writeOrderQueue(WTSOrdQueData* curOrdQue) override {
        if (curOrdQue) {
            ordque_count_++;
            return true;
        }
        return false;
    }
    
    virtual bool writeOrderDetail(WTSOrdDtlData* curOrdDetail) override {
        if (curOrdDetail) {
            orddtl_count_++;
            return true;
        }
        return false;
    }
    
    virtual bool writeTransaction(WTSTransData* curTrans) override {
        if (curTrans) {
            trans_count_++;
            return true;
        }
        return false;
    }
    
    // 测试辅助方法
    int getTickCount() const { return tick_count_.load(); }
    int getOrdQueCount() const { return ordque_count_.load(); }
    int getOrdDtlCount() const { return orddtl_count_.load(); }
    int getTransCount() const { return trans_count_.load(); }
};

/*!
 * \brief 数据接口综合测试夹具类
 */
class DataInterfacesTest : public ::testing::Test {
protected:
    void SetUp() override {
        mock_base_data_mgr_ = std::make_unique<MockIBaseDataMgr>();
        mock_hot_mgr_ = std::make_unique<MockIHotMgr>();
        mock_reader_sink_ = std::make_unique<MockIDataReaderSink>();
        mock_his_loader_ = std::make_unique<MockIHisDataLoader>();
        mock_data_reader_ = std::make_unique<MockIDataReader>();
        mock_writer_sink_ = std::make_unique<MockIDataWriterSink>();
        mock_his_dumper_ = std::make_unique<MockIHisDataDumper>();
        mock_data_writer_ = std::make_unique<MockIDataWriter>();
        
        // 设置基础返回值
        EXPECT_CALL(*mock_reader_sink_, get_basedata_mgr())
            .WillRepeatedly(::testing::Return(mock_base_data_mgr_.get()));
        EXPECT_CALL(*mock_reader_sink_, get_hot_mgr())
            .WillRepeatedly(::testing::Return(mock_hot_mgr_.get()));
        EXPECT_CALL(*mock_reader_sink_, get_date())
            .WillRepeatedly(::testing::Return(20241201));
        EXPECT_CALL(*mock_reader_sink_, get_min_time())
            .WillRepeatedly(::testing::Return(1500));
            
        EXPECT_CALL(*mock_writer_sink_, get_basedata_mgr())
            .WillRepeatedly(::testing::Return(mock_base_data_mgr_.get()));
        EXPECT_CALL(*mock_writer_sink_, getTradingDate(::testing::_))
            .WillRepeatedly(::testing::Return(20241201));
    }
    
    void TearDown() override {
        // 清理资源
    }
    
    std::unique_ptr<MockIBaseDataMgr> mock_base_data_mgr_;
    std::unique_ptr<MockIHotMgr> mock_hot_mgr_;
    std::unique_ptr<MockIDataReaderSink> mock_reader_sink_;
    std::unique_ptr<MockIHisDataLoader> mock_his_loader_;
    std::unique_ptr<MockIDataReader> mock_data_reader_;
    std::unique_ptr<MockIDataWriterSink> mock_writer_sink_;
    std::unique_ptr<MockIHisDataDumper> mock_his_dumper_;
    std::unique_ptr<MockIDataWriter> mock_data_writer_;
};

/*!
 * \brief 测试数据读取器初始化
 */
TEST_F(DataInterfacesTest, TestDataReaderInitialization) {
    WTSVariant* config = WTSVariant::createObject();
    config->append("path", "./data", false);
    config->append("cache", true, false);
    
    mock_data_reader_->init(config, mock_reader_sink_.get(), mock_his_loader_.get());
    
    config->release();
    
    std::cout << "数据读取器初始化测试通过" << std::endl;
}

/*!
 * \brief 测试分钟线结束处理
 */
TEST_F(DataInterfacesTest, TestMinuteEndProcessing) {
    mock_data_reader_->init(nullptr, mock_reader_sink_.get(), mock_his_loader_.get());
    
    // 设置期望的回调
    EXPECT_CALL(*mock_reader_sink_, on_all_bar_updated(::testing::_))
        .Times(1);
    
    EXPECT_CALL(*mock_data_reader_, onMinuteEnd(20241201, 1500, 0))
        .Times(1);
    
    mock_data_reader_->onMinuteEnd(20241201, 1500, 0);
    
    std::cout << "分钟线结束处理测试通过" << std::endl;
}

/*!
 * \brief 测试K线数据读取
 */
TEST_F(DataInterfacesTest, TestKlineDataReading) {
    mock_data_reader_->init(nullptr, mock_reader_sink_.get(), mock_his_loader_.get());
    
    // 添加测试数据
    WTSBarStruct test_bar;
    memset(&test_bar, 0, sizeof(test_bar));
    test_bar.date = 20241201;
    test_bar.time = 1500;
    test_bar.open = 3800.0;
    test_bar.high = 3850.0;
    test_bar.low = 3780.0;
    test_bar.close = 3820.0;
    test_bar.vol = 1000;
    
    mock_data_reader_->addTestKlineData("SHFE.au2501", test_bar);
    EXPECT_EQ(mock_data_reader_->getKlineDataCount("SHFE.au2501"), 1);
    
    // 测试读取K线切片
    WTSKlineSlice* slice = mock_data_reader_->readKlineSlice("SHFE.au2501", KP_Minute1, 100, 0);
    // 由于是mock实现，返回nullptr是正常的
    
    std::cout << "K线数据读取测试通过" << std::endl;
}

/*!
 * \brief 测试复权因子获取
 */
TEST_F(DataInterfacesTest, TestAdjustmentFactors) {
    mock_data_reader_->init(nullptr, mock_reader_sink_.get(), mock_his_loader_.get());
    
    // 测试默认复权因子
    double factor = mock_data_reader_->getAdjFactorByDate("SSE.600000", 20241201);
    EXPECT_EQ(factor, 1.0);
    
    // 测试历史数据加载器的复权因子加载
    EXPECT_CALL(*mock_his_loader_, loadAdjFactors(::testing::_, ::testing::_, ::testing::_))
        .WillOnce(::testing::Return(true));
    
    bool result = mock_his_loader_->loadAdjFactors(nullptr, "SSE.600000", nullptr);
    EXPECT_TRUE(result);
    
    std::cout << "复权因子测试通过" << std::endl;
}

/*!
 * \brief 测试数据写入器初始化
 */
TEST_F(DataInterfacesTest, TestDataWriterInitialization) {
    WTSVariant* config = WTSVariant::createObject();
    config->append("path", "./output", false);
    config->append("compress", true, false);
    
    bool result = mock_data_writer_->init(config, mock_writer_sink_.get());
    EXPECT_TRUE(result);
    
    config->release();
    
    std::cout << "数据写入器初始化测试通过" << std::endl;
}

/*!
 * \brief 测试Tick数据写入
 */
TEST_F(DataInterfacesTest, TestTickDataWriting) {
    mock_data_writer_->init(nullptr, mock_writer_sink_.get());
    
    // 创建测试tick数据
    WTSTickData* tick = WTSTickData::create("SHFE.au2501");
    tick->setPrice(3820.0);
    tick->setVolume(100);
    tick->setTurnover(382000.0);
    tick->setOpenInterest(50000);
    
    // 设置广播期望
    EXPECT_CALL(*mock_writer_sink_, broadcastTick(::testing::_))
        .Times(1);
    
    // 写入数据
    bool result = mock_data_writer_->writeTick(tick, 0);
    EXPECT_TRUE(result);
    EXPECT_EQ(mock_data_writer_->getTickCount(), 1);
    
    // 广播数据
    mock_writer_sink_->broadcastTick(tick);
    
    tick->release();
    
    std::cout << "Tick数据写入测试通过，写入数量: " << mock_data_writer_->getTickCount() << std::endl;
}

/*!
 * \brief 测试Level2数据写入
 */
TEST_F(DataInterfacesTest, TestLevel2DataWriting) {
    mock_data_writer_->init(nullptr, mock_writer_sink_.get());
    
    // 测试委托队列数据写入（使用nullptr模拟，因为实际创建较复杂）
    // 在实际实现中应该创建真实的数据对象
    
    // 模拟写入操作
    int initial_count = mock_data_writer_->getOrdQueCount();
    
    // 由于传入nullptr，写入应该失败
    bool result = mock_data_writer_->writeOrderQueue(nullptr);
    EXPECT_FALSE(result);
    EXPECT_EQ(mock_data_writer_->getOrdQueCount(), initial_count);
    
    std::cout << "Level2数据写入测试通过" << std::endl;
}

/*!
 * \brief 测试历史数据导出
 */
TEST_F(DataInterfacesTest, TestHistoricalDataDumping) {
    // 测试K线数据导出
    EXPECT_CALL(*mock_his_dumper_, dumpHisBars(::testing::_, ::testing::_, ::testing::_, ::testing::_))
        .WillOnce(::testing::Return(true));
    
    bool result = mock_his_dumper_->dumpHisBars("SHFE.au2501", "m1", nullptr, nullptr);
    EXPECT_TRUE(result);
    
    // 测试Tick数据导出
    EXPECT_CALL(*mock_his_dumper_, dumpHisTicks(::testing::_, ::testing::_, ::testing::_, ::testing::_))
        .WillOnce(::testing::Return(true));
    
    result = mock_his_dumper_->dumpHisTicks("SHFE.au2501", 20241201, nullptr, nullptr);
    EXPECT_TRUE(result);
    
    std::cout << "历史数据导出测试通过" << std::endl;
}

/*!
 * \brief 测试数据处理性能
 */
TEST_F(DataInterfacesTest, TestDataProcessingPerformance) {
    mock_data_writer_->init(nullptr, mock_writer_sink_.get());
    
    const int test_count = 1000;
    auto start_time = std::chrono::high_resolution_clock::now();
    
    // 模拟大量数据写入
    for (int i = 0; i < test_count; ++i) {
        WTSTickData* tick = WTSTickData::create("PERF.test");
        tick->setPrice(100.0 + i * 0.01);
        tick->setVolume(100 + i);
        
        mock_data_writer_->writeTick(tick, 0);
        tick->release();
    }
    
    auto end_time = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
    
    EXPECT_EQ(mock_data_writer_->getTickCount(), test_count);
    
    double ticks_per_second = (double)test_count * 1000000.0 / duration.count();
    
    std::cout << "数据处理性能测试结果:" << std::endl;
    std::cout << "  处理数据量: " << test_count << " 条" << std::endl;
    std::cout << "  总耗时: " << duration.count() << " 微秒" << std::endl;
    std::cout << "  处理速度: " << static_cast<int>(ticks_per_second) << " 条/秒" << std::endl;
    
    EXPECT_GT(ticks_per_second, 10000); // 期望至少10000条/秒的处理能力
}

/*!
 * \brief 测试完整数据流程
 */
TEST_F(DataInterfacesTest, TestCompleteDataWorkflow) {
    // 1. 初始化读写器
    mock_data_reader_->init(nullptr, mock_reader_sink_.get(), mock_his_loader_.get());
    mock_data_writer_->init(nullptr, mock_writer_sink_.get());
    
    // 2. 设置回调期望
    EXPECT_CALL(*mock_reader_sink_, on_bar(::testing::_, ::testing::_, ::testing::_))
        .Times(::testing::AtLeast(0));
    
    EXPECT_CALL(*mock_writer_sink_, broadcastTick(::testing::_))
        .Times(::testing::AtLeast(1));
    
    // 3. 模拟数据写入
    WTSTickData* tick = WTSTickData::create("WORKFLOW.test");
    tick->setPrice(1000.0);
    tick->setVolume(500);
    
    bool write_result = mock_data_writer_->writeTick(tick, 0);
    EXPECT_TRUE(write_result);
    
    // 4. 广播数据
    mock_writer_sink_->broadcastTick(tick);
    
    // 5. 模拟分钟结束处理
    EXPECT_CALL(*mock_data_reader_, onMinuteEnd(20241201, 1500, 0))
        .Times(1);
    
    mock_data_reader_->onMinuteEnd(20241201, 1500, 0);
    
    // 6. 清理资源
    tick->release();
    
    std::cout << "完整数据流程测试通过:" << std::endl;
    std::cout << "  写入Tick数: " << mock_data_writer_->getTickCount() << std::endl;
    std::cout << "  当前交易日: " << mock_reader_sink_->get_date() << std::endl;
    std::cout << "  当前时间: " << mock_reader_sink_->get_min_time() << std::endl;
} 